#region Copyright

// The contents of this file are subject to the Mozilla Public License
//  Version 1.1 (the "License"); you may not use this file except in compliance
//  with the License. You may obtain a copy of the License at
//  
//  http://www.mozilla.org/MPL/
//  
//  Software distributed under the License is distributed on an "AS IS"
//  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
//  License for the specific language governing rights and limitations under 
//  the License.
//  
//  The Initial Developer of the Original Code is Robert Smyth.
//  Portions created by Robert Smyth are Copyright (C) 2008.
//  
//  All Rights Reserved.

#endregion

using System.Collections.Generic;
using System.IO;
using Alchemi.Core.Owner;
using NUnit.Extensions.NUnitGridRunner.Metrics;


namespace NUnit.Extensions.NUnitGridRunner
{
    public class GridThreadGenerator
    {
        private readonly string assemblyFileName;
        private readonly string executorApplicationPath;
        private readonly bool networkTestMode;
        private readonly IGridRunnerFactory runnerFactory;
        private readonly ISuiteMetrics suiteMetrics;
        private readonly string testResultsFolderName;
        public bool failed;

        public GridThreadGenerator(string executorApplicationPath, string assemblyFileName, string testResultsFolderName,
                                   ISuiteMetrics suiteMetrics, IGridRunnerFactory runnerFactory, bool networkTestMode)
        {
            this.executorApplicationPath = executorApplicationPath;
            this.assemblyFileName = assemblyFileName;
            this.testResultsFolderName = testResultsFolderName;
            this.suiteMetrics = suiteMetrics;
            this.runnerFactory = runnerFactory;
            this.networkTestMode = networkTestMode;
        }

        public bool Succeeded
        {
            get { return !failed; }
        }

        public GThread[] GetGridThreads(string[][] executorFixtures)
        {
            var gridThreads = new List<GThread>();

            int threadID = 1;
            foreach (string[] fixtures in executorFixtures)
            {
                int fixtureID = 1;
                var commandLines = new List<string>();

                foreach (string fixture in fixtures)
                {
                    string xmlResultsFileName = Path.Combine(executorApplicationPath, testResultsFolderName);
                    xmlResultsFileName =
                        Path.Combine(xmlResultsFileName,
                                     string.Format("TestResults{0:0##}-{1:0###}.xml", threadID++, fixtureID++));

                    string commandLine = string.Format("/run:{0} {1} /domain=none /nologo /nothread /xml={2}",
                                                       fixture,
                                                       Path.Combine(executorApplicationPath,
                                                                    assemblyFileName),
                                                       xmlResultsFileName);
                    commandLines.Add(commandLine);
                }

                GThread runner =
                    runnerFactory.Create(commandLines.ToArray(), fixtures, suiteMetrics.GetExpectedTime(fixtures),
                                         assemblyFileName, networkTestMode);

                gridThreads.Add(runner);
            }

            return gridThreads.ToArray();
        }
    }
}